// XMLLib version 1
//
// Author
//
//   Thomas Koos (info@muetze1.de)
//   www.muetze1.de
//
// License
//
//   This Source Code Form is subject to the terms of the Mozilla Public
//   License, v. 1.1. If a copy of the MPL was not distributed with this
//   file, You can obtain one at http://mozilla.org/MPL/1.1/.
//
// Copyright
//
//   Because MatchesMask() is only available in the commercial versions
//   of Delphi, I added this function to be independend. The function
//   based on a public domain C function I found some years ago in the
//   internet. Unfortunately I have no URL. If you know any, please inform
//   me.
//
// Description
//
//   Helper functions for string comparsion using placeholders * and ?.
//
// Revision
//
//  $Id: StrMasks.pas 18 2014-04-21 21:28:10Z muetze1@gmail.com $
//

Unit StrMasks;

Interface

{$Z+}  // equal to $Z4 on newer compilers

    // The functions returns if the passed string matches the given mask. The mask can
    // contain placeholders like known from the filesystem functions (* and ?).
  Function MaskMatch(Const AMask, AString: String): Boolean;

Implementation

const
  MAX_CALLS = 200;

Function MaskMatch(Const AMask, AString: String): Boolean;
Var
  Calls, Wild: Integer;
  lMask, lString,
  m, n, ma, na: PChar;
Begin
  Calls := 0;
  Wild := 0;

  Result := True;

  lMask   := PChar(AMask);
  lString := PChar(AString);

  m  := lMask;
  n  := lString;
  ma := lMask;
  na := lString;

  While True Do
  Begin
    Inc(Calls);
    If ( Calls > MAX_CALLS ) Then
    Begin
      Result := False;
      Exit;
    End;

    If ( m^ = '*' ) Then
    Begin
      While ( m^ = '*' ) Do
        Inc(m);

      wild := 1;
      ma   := m;
      na   := n;
    End;

    If ( m^ = #0 ) Then
    Begin
      If ( n^ = #0 ) Then
        Exit;

      Dec(m);
      While ( ( m > lMask ) And ( m^ = '?' ) ) Do
        Dec(m);

      If ( ( m^ = '*' ) And ( m > lMask ) ) Then
        Exit;

      If ( wild = 0 ) Then
      Begin
        Result := False;
        Exit;
      End;

      m := ma;
    End
    Else If ( n^ = #0 ) Then
    Begin
      While ( m^ = '*' ) Do
        Inc(m);

      Result := ( m^ = #0 );
      Exit;
    End;

    If ( ( UpCase(m^) <> UpCase(n^) ) And ( m^ <> '?' ) ) Then
    Begin
      If ( wild = 0 ) Then
      Begin
        Result := False;
        Exit;
      End;

      m := ma;
      Inc(na);
      n := na;
    End
    Else
    Begin
      If ( m^ <> #0 ) Then
        Inc(m);
      If ( n^ <> #0 ) Then
        Inc(n);
    End;
  End;
End;

End.





